package main

import (
	"fmt"
	"math"
	"sort"
)

// 接口规范 面积的方法
type Interface interface {
	Measure() float64
}

// 圆形
type Circle struct {
	Radius float64
}

func NewCircle(r float64) *Circle {
	return &Circle{Radius: r}
}

func (c *Circle) String() string {
	return fmt.Sprintf("%T=%f", c, c.Measure())
}

// 三角形
type Triangle struct {
	Edge float64
	Tall float64
}

func NewTriangle(e, ta float64) *Triangle {
	return &Triangle{
		Edge: e,
		Tall: ta,
	}
}

func (t *Triangle) String() string {
	return fmt.Sprintf("%T=%f", t, t.Measure())
}

// 长方形
type Rectangle struct {
	Lang float64
	Wide float64
}

func NewRectangle(l, w float64) *Rectangle {
	return &Rectangle{
		Lang: l,
		Wide: w,
	}
}

func (r *Rectangle) String() string {
	return fmt.Sprintf("%T=%f", r, r.Measure())
}

func (c *Circle) Measure() float64 {
	return math.Pi * c.Radius * c.Radius
}

func (t *Triangle) Measure() float64 {
	return t.Edge * t.Tall / 2.0
}

func (r *Rectangle) Measure() float64 {
	return r.Lang * r.Wide
}

func main() {
	c := NewCircle(3.3)
	fmt.Println(c, c.Measure())
	t := NewTriangle(5.1, 2.3)
	fmt.Println(t, t.Measure())
	r := NewRectangle(9.5, 8.8)
	fmt.Println(r, r.Measure())
	fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")

	var ll = []Interface{c, t, r}
	fmt.Println(ll)
	sort.Slice(ll, func(i, j int) bool {
		return ll[i].Measure() < ll[j].Measure()
	})
	fmt.Println(ll)
	fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")

	for _, v := range ll {
		fmt.Printf("%T\t%.2f\n", v, v.Measure())
	}
}
